package com.xxx.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.xxx.config.RedissonConfig;
import com.xxx.domain.KillActivity;
import com.xxx.domain.KillCourse;
import com.xxx.mapper.KillActivityMapper;
import com.xxx.service.IKillActivityService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.xxx.service.IKillCourseService;
import com.xxx.util.AssertUtil;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jh
 * @since 2025-09-16
 */
@Service
public class KillActivityServiceImpl extends ServiceImpl<KillActivityMapper, KillActivity> implements IKillActivityService {
    private static final Logger log = LoggerFactory.getLogger(KillActivityServiceImpl.class);
    /**
     * 条件判断
     *
     * @param entity
     * @return
     */
    SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm");
    @Autowired
    private IKillCourseService killCourseService;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Override
    public boolean insert(KillActivity entity) {
        boolean before = entity.getBeginTime().before(entity.getEndTime());
        AssertUtil.isTrue(before, "开始时间应该在结束时间之前");
        //boolean after = entity.getBeginTime().after(new Date());
        //AssertUtil.isTrue(after, "开始时间应该在当前时间之后");
        Date now = new Date();
        entity.setCreateTime(now);
        entity.setPublishStatus(KillActivity.PUBLISH_STATUS_WAIT);
        entity.setTimeStr(sdf.format(entity.getBeginTime()));//取出开始时间的月日,转成字符串
        boolean insert = super.insert(entity);
        AssertUtil.isTrue(insert, "添加失败");
        return insert;
    }

    /**
     * 发布秒杀活动
     *
     * @param activityId
     */
    @Override
    public void publish(String activityId) {
        KillActivity killActivity = selectById(activityId);
        AssertUtil.isNotNull(killActivity, "待发布的秒杀活动不存在...");
        AssertUtil.isEquals(killActivity.getPublishStatus(), KillActivity.PUBLISH_STATUS_WAIT,
                "秒杀活动已经发布");
        Date now = new Date();
        killActivity.setPublishStatus(KillActivity.PUBLISH_STATUS_PUBLISH);
        killActivity.setPublishTime(now);
        boolean update = updateById(killActivity);

        EntityWrapper<KillCourse> wrapper = new EntityWrapper<>();
        wrapper.eq("activity_id", activityId);
        List<KillCourse> killCourses = killCourseService.selectList(wrapper);
        AssertUtil.isTrue(!killCourses.isEmpty(), "该活动下无秒杀课程");
        for (KillCourse killCourse : killCourses) {
            RSemaphore semaphore =
                    redissonClient.getSemaphore("activityId:" + activityId + ":" + "courseId:" +
                            killCourse.getCourseId());
            boolean b = semaphore.trySetPermits(killCourse.getKillCount());//设置信号(库存)量
            if (b) {
                killCourse.setPublishStatus(KillCourse.PUBLISH_STATUS_PUBLISH);
                killCourse.setPublishTime(now);
                killCourseService.updateById(killCourse);
                redisTemplate.opsForHash().put("activity:" + activityId,
                        "activityId:" + activityId + ":" + "courseId:" +
                                killCourse.getCourseId(), killCourse);
            } else {
                log.error("活动{}的{}课程缓存预热失败", activityId, killCourse.getCourseId());
            }
        }

    }
}
